#!/usr/bin/env python
# Purpose: Data export for HydroPlatform
# Author:
#    Hossam Almeer <halmeer@cs.ucl.ac.uk>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with HydroPlatform for details.

import codecs
from itertools import count, chain
import logging
import numpy
import os
import sets
import datetime
import hydroplatform

from sqlalchemy import and_

from hydroplatform.model import network as nt
from hydroplatform.model import fields as fd
from hydroplatform.model import units
from hydroplatform.model import database as db

#nt.Project = Project 

def_db_session = 0   # Default sqlalchemy session = most recent session opened

def open_db_con(dbcon):
    '''
    Takes a filepath, and returns an sqlalchemy session object\
    which is stored in memory
    '''

    dbs = db.get_session(dbcon)
    print 'Opening db connection ........'
    print dbs
    global def_db_session
    def_db_session = dbs
    return dbs


def get_projects(dbsession):
    '''
    Takes a db connection, and returns a list of projects in the DB,\
    this is a query, which returns results from both db and flushed 
    parts of uncommited trasactions. Autoflush occurs here, although\
    this can be disabled in sqlalchemy.
    '''

    projects_list = dbsession.query(nt.Project).all()
    return projects_list


def get_parent_project(net):
    '''
    Returns project of a network
    '''
    return net.project


def get_timeframe(proj_net):
    '''
    Passing in a project or a network will return the horizon and time step\
    of the project.
    '''
    if isinstance(proj_net,nt.Network):
        proj_net = proj_net.project
    times_list = [proj_net.horizon_from, proj_net.horizon_to, proj_net.time_step]
    return times_list

def get_networks(proj):
    '''
    Takes a project object, and returns a list of networks
    in the project
    '''
    return proj.networks


def get_network_nodes(net):
    
    return net.nodes


def get_network_links(net):
    
    return net.links


def commit(dbs):
    '''
    Does a flush() and sends changes to external DB (a transaction). \
    You could use dbs.commit().
    '''

    dbs.commit()  # local function of sqlalchemy session object
                  # see sqlalchemy doc for possible errors/return values
    return 0      # 0 for returning successfully 

def flush(dbs):
    '''
    flushing session object sends changes to db stored in memory,\
    NOT to the external DB. By default, this occurs automatically\
    when a query is made. 
    '''
    
    dbs.flush() # Note that flush failure causes rollback(dbs)
    return 0

def rollback(dbs):
    '''
    Rolls back all transactions, plus other effects. See:
    http://docs.sqlalchemy.org/en/latest/orm/session.html#rolling-back
    '''

    dbs.rollback()
    return 0

def get_field_type(field):
    '''
    Returns a string with the type of the field
    '''

    if isinstance(field.attribute_type, fd.Parameter):
        return "Parameter"
    elif isinstance(field.attribute_type, fd.TimeSerie):
        return "Time_Series"
    elif isinstance(field.attribute_type, fd.NodeReferences):
        return "Node_References"
    elif isinstance(field.attribute_type, fd.LinkReferences):
        return "Link_References"
    elif isinstance(field.attribute_type, fd.SeasonalParameter):
        return "Sesonal_Parameter"
    elif isinstance(field.attribute_type, fd.Table):
        return "Table"
'''
MARK : Need to work on convenient way to get object field values.
More Importantly, need to find a way to set field values easily.
Should be able to set a NodeFiled.value item to w/e I want
'''

def main():
    try:
        dbcon= 'sqlite:///C:\Users\H\hydroplatform.db' 
        dbs = open_db_con(dbcon)
        proj_list = get_projects(dbs)
        assert type(proj_list) == list 
        net_list = get_networks(proj_list[0])
        assert type(net_list) == list


    except:
        print 'Tests Failed'


if __name__=='__main__':

	main()










